﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using Providers;
using System.Xml.Linq;
using XMLProviders.Extensions;

namespace XMLProviders
{
    /// <summary>
    /// Manage user configuration files
    /// </summary>
    public class UserConfigurationProvider : IUserConfigurationProvider
    {
        #region Public

        /// <summary>
        /// Load the users configuraation data
        /// </summary>
        /// <param name="errorMsg">Any error message that is generated as part of this process</param>
        /// <returns>The loaded user configuration</returns>
        public Models.UserConfiguration LoadUserConfiguration(out string errorMsg)
        {
            // Create a default set of config data
            Models.UserConfiguration userConfig = new Models.UserConfiguration();

            // Get the settings file path
            string settingsFile = GetSettingsFilePath(out errorMsg);

            if (!string.IsNullOrEmpty(settingsFile))
            {
                try
                {
                    XDocument configDataFile = XDocument.Load(settingsFile);

                    var configData = configDataFile.Descendants().FirstOrDefault(x => x.Name == "UserConfiguration");

                    if (configData != null)
                    {
                        // Load configuration data here when we have anything to load
                    }
                }
                catch (FileNotFoundException)
                {
                    // File not found so try and save the default configuration we created at the start
                    SaveUserConfiguration(userConfig, out errorMsg);
                }
                catch (Exception ex)
                {
                    // Something has gone wrong so display an error message
                    errorMsg = ex.Message;
                }
            }

            return userConfig;
        }

        /// <summary>
        /// Save the current state of the users configuration
        /// </summary>
        /// <param name="userConfig">The user configuration data to save</param>
        /// <param name="errorMsg">Any error message that is generated as part of this process</param>
        /// <returns>True if the save was successful, otherwise false</returns>
        public bool SaveUserConfiguration(Models.UserConfiguration userConfig, out string errorMsg)
        {
            bool result = false;

            // Get the settings file path
            string settingsFile = GetSettingsFilePath(out errorMsg);

            if (!string.IsNullOrEmpty(settingsFile))
            {
                // Build XML
                XDocument configDataXml = new XDocument(
                    new XElement("UserConfiguration",
                        new XElement("configFileVersion", "2")));

                // Attempt to save it
                try
                {
                    configDataXml.Save(settingsFile);
                    result = true;
                }
                catch (Exception ex)
                {
                    // SOmething went wrong so set the error message
                    errorMsg = ex.Message;
                }
            }

            return result;
        }

        #endregion Public

        #region Private

        /// <summary>
        /// Return the path and file name to use for the settings file
        /// </summary>
        /// <param name="errorMsg">Any error message or string. empty if there was no error</param>
        /// <returns>The location of the settings file (along with the file name)</returns>
        private string GetSettingsFilePath(out string errorMsg)
        {
            // Assume we have the path
            bool pathExists = true;

            // Construct the path at which the userConfig.xml file will be stored
            string localSettings = Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData);
            string settingsPath = Path.Combine(localSettings, "SuperQuery");

            // If settingsPath does not exist then we need to try and create it
            if (!Directory.Exists(settingsPath))
            {
                try
                {
                    Directory.CreateDirectory(settingsPath);
                }
                catch (Exception)
                {
                    pathExists = false;
                }
            }

            string result;

            // If we have a valid path then add the file name to it, otherwise return an error message in errorMsg
            if (pathExists)
            {
                result = Path.Combine(settingsPath, "userConfig.xml");
                errorMsg = string.Empty;
            }
            else
            {
                result = string.Empty;
                errorMsg = string.Format("Unable to locate the userConfig.xml file at the following location: {0}", settingsPath);
            }

            return result;
        }

        #endregion Private
    }
}
